x86: add platform hypercall to retrieve pCPU-s' family, model, and stepping
authorJan Beulich <jbeulich@suse.com>
Tue, 13 Dec 2011 08:48:51 +0000 (09:48 +0100)
committerJan Beulich <jbeulich@suse.com>
Tue, 13 Dec 2011 08:48:51 +0000 (09:48 +0100)
With the recent hotplug changes to the Xen part of the microcode
loading, this allows the kernel driver to avoid unnecessary calls into
the hypervisor during pCPU hot-enabling: Knowing that the hypervisor
retains the data for already booted CPUs, only data for CPUs with a
different signature needs to be passed down. Since the microcode
loading code can be pretty verbose, avoiding to invoke it can make the
log much easier to look at in case of problems.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
xen/arch/x86/platform_hypercall.c
xen/arch/x86/x86_64/platform_hypercall.c
xen/include/public/platform.h
xen/include/xlat.lst

index 1cb8ff39db867e05cebff1b26a2c49508d926266..a0d23ba0d2dff8d1e268c25ce5cb248cf3fd5470 100644 (file)
@@ -469,6 +469,42 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
     }
     break;
 
+    case XENPF_get_cpu_version:
+    {
+        struct xenpf_pcpu_version *ver = &op->u.pcpu_version;
+
+        if ( !get_cpu_maps() )
+        {
+            ret = -EBUSY;
+            break;
+        }
+
+        if ( (ver->xen_cpuid >= nr_cpu_ids) || !cpu_online(ver->xen_cpuid) )
+        {
+            memset(ver->vendor_id, 0, sizeof(ver->vendor_id));
+            ver->family = 0;
+            ver->model = 0;
+            ver->stepping = 0;
+        }
+        else
+        {
+            const struct cpuinfo_x86 *c = &cpu_data[ver->xen_cpuid];
+
+            memcpy(ver->vendor_id, c->x86_vendor_id, sizeof(ver->vendor_id));
+            ver->family = c->x86;
+            ver->model = c->x86_model;
+            ver->stepping = c->x86_mask;
+        }
+
+        ver->max_present = cpumask_last(&cpu_present_map);
+
+        put_cpu_maps();
+
+        if ( copy_field_to_guest(u_xenpf_op, op, u.pcpu_version) )
+            ret = -EFAULT;
+    }
+    break;
+
     case XENPF_cpu_online:
     {
         int cpu = op->u.cpu_ol.cpuid;
index a1d41c2be257f9973d2eb9d1af1e28294d5126a2..188aa375f5f7d86a8403e07c8d7dfbddc5469ecf 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 #include <xen/config.h>
-#include <xen/types.h>
+#include <xen/lib.h>
 #include <compat/platform.h>
 
 DEFINE_XEN_GUEST_HANDLE(compat_platform_op_t);
@@ -26,8 +26,13 @@ DEFINE_XEN_GUEST_HANDLE(compat_platform_op_t);
 #define xen_processor_power_t   compat_processor_power_t
 #define set_cx_pminfo           compat_set_cx_pminfo
 
-#define xenpf_pcpuinfo compat_pf_pcpuinfo
-#define xenpf_pcpuinfo_t compat_pf_pcpuinfo_t
+#define xen_pf_pcpuinfo xenpf_pcpuinfo
+CHECK_pf_pcpuinfo;
+#undef xen_pf_pcpuinfo
+
+#define xen_pf_pcpu_version xenpf_pcpu_version
+CHECK_pf_pcpu_version;
+#undef xen_pf_pcpu_version
 
 #define xenpf_enter_acpi_sleep compat_pf_enter_acpi_sleep
 
index 28ce37588105bd255b0b1da7e12565dd77d0399a..7b8d6e8dd57f56204e5e6add5ef4996226cdb3d9 100644 (file)
@@ -449,6 +449,21 @@ struct xenpf_pcpuinfo {
 typedef struct xenpf_pcpuinfo xenpf_pcpuinfo_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_pcpuinfo_t);
 
+#define XENPF_get_cpu_version 48
+struct xenpf_pcpu_version {
+    /* IN */
+    uint32_t xen_cpuid;
+    /* OUT */
+    /* The maxium cpu_id that is present */
+    uint32_t max_present;
+    char vendor_id[12];
+    uint32_t family;
+    uint32_t model;
+    uint32_t stepping;
+};
+typedef struct xenpf_pcpu_version xenpf_pcpu_version_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_pcpu_version_t);
+
 #define XENPF_cpu_online    56
 #define XENPF_cpu_offline   57
 struct xenpf_cpu_ol
@@ -492,6 +507,7 @@ struct xen_platform_op {
         struct xenpf_getidletime       getidletime;
         struct xenpf_set_processor_pminfo set_pminfo;
         struct xenpf_pcpuinfo          pcpu_info;
+        struct xenpf_pcpu_version      pcpu_version;
         struct xenpf_cpu_ol            cpu_ol;
         struct xenpf_cpu_hotadd        cpu_add;
         struct xenpf_mem_hotadd        mem_add;
index fcf692255ba6b6538da0fe797a6073b7d96e3a59..068e92fd74a3428a2c13fcfbf759dd907a268bf2 100644 (file)
 ?      physdev_restore_msi             physdev.h
 ?      physdev_set_iopl                physdev.h
 ?      physdev_setup_gsi               physdev.h
+!      pct_register                    platform.h
+!      power_register                  platform.h
+?      processor_csd                   platform.h
+!      processor_cx                    platform.h
+!      processor_flags                 platform.h
+!      processor_performance           platform.h
+!      processor_power                 platform.h
+?      processor_px                    platform.h
+!      psd_package                     platform.h
+?      xenpf_pcpuinfo                  platform.h
+?      xenpf_pcpu_version              platform.h
 !      sched_poll                      sched.h
 ?      sched_remote_shutdown           sched.h
 ?      sched_shutdown                  sched.h
 !      vcpu_set_singleshot_timer       vcpu.h
 ?      xenoprof_init                   xenoprof.h
 ?      xenoprof_passive                xenoprof.h
-!      power_register                  platform.h
-?      processor_csd                   platform.h
-!      processor_cx                    platform.h
-!      processor_flags                 platform.h
-!      processor_power                 platform.h
-!      pct_register                    platform.h
-?      processor_px                    platform.h
-!      psd_package                     platform.h
-!      processor_performance           platform.h